home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / stdlib / RCS / strtol.c,v < prev    next >
Encoding:
Text File  |  1989-03-22  |  5.7 KB  |  304 lines

  1. head     1.4;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.4
  10. date     89.03.22.00.47.30;  author rab;  state Exp;
  11. branches ;
  12. next     1.3;
  13.  
  14. 1.3
  15. date     88.07.25.11.10.46;  author ouster;  state Exp;
  16. branches ;
  17. next     1.2;
  18.  
  19. 1.2
  20. date     88.06.17.18.00.08;  author ouster;  state Exp;
  21. branches ;
  22. next     1.1;
  23.  
  24. 1.1
  25. date     88.04.28.17.20.29;  author ouster;  state Exp;
  26. branches ;
  27. next     ;
  28.  
  29.  
  30. desc
  31. @@
  32.  
  33.  
  34. 1.4
  35. log
  36. @*** empty log message ***
  37. @
  38. text
  39. @/* 
  40.  * strtol.c --
  41.  *
  42.  *    Source code for the "strtol" library procedure.
  43.  *
  44.  * Copyright 1988 Regents of the University of California
  45.  * Permission to use, copy, modify, and distribute this
  46.  * software and its documentation for any purpose and without
  47.  * fee is hereby granted, provided that the above copyright
  48.  * notice appear in all copies.  The University of California
  49.  * makes no representations about the suitability of this
  50.  * software for any purpose.  It is provided "as is" without
  51.  * express or implied warranty.
  52.  */
  53.  
  54. #ifndef lint
  55. static char rcsid[] = "$Header: /sprite/src/lib/c/stdlib/RCS/strtol.c,v 1.3 88/07/25 11:10:46 ouster Exp Locker: rab $ SPRITE (Berkeley)";
  56. #endif /* not lint */
  57.  
  58. #include <stdlib.h>
  59. #include <ctype.h>
  60.  
  61.  
  62. /*
  63.  *----------------------------------------------------------------------
  64.  *
  65.  * strtol --
  66.  *
  67.  *    Convert an ASCII string into an integer.
  68.  *
  69.  * Results:
  70.  *    The return value is the integer equivalent of string.  If endPtr
  71.  *    is non-NULL, then *endPtr is filled in with the character
  72.  *    after the last one that was part of the integer.  If string
  73.  *    doesn't contain a valid integer value, then zero is returned
  74.  *    and *endPtr is set to string.
  75.  *
  76.  * Side effects:
  77.  *    None.
  78.  *
  79.  *----------------------------------------------------------------------
  80.  */
  81.  
  82. long int
  83. strtol(string, endPtr, base)
  84.     char *string;        /* String of ASCII digits, possibly
  85.                  * preceded by white space.  For bases
  86.                  * greater than 10, either lower- or
  87.                  * upper-case digits may be used.
  88.                  */
  89.     char **endPtr;        /* Where to store address of terminating
  90.                  * character, or NULL. */
  91.     int base;            /* Base for conversion.  Must be less
  92.                  * than 37.  If 0, then the base is chosen
  93.                  * from the leading characters of string:
  94.                  * "0x" means hex, "0" means octal, anything
  95.                  * else means decimal.
  96.                  */
  97. {
  98.     register char *p;
  99.     int result;
  100.  
  101.     /*
  102.      * Skip any leading blanks.
  103.      */
  104.  
  105.     p = string;
  106.     while (isspace(*p)) {
  107.     p += 1;
  108.     }
  109.  
  110.     /*
  111.      * Check for a sign.
  112.      */
  113.  
  114.     if (*p == '-') {
  115.     p += 1;
  116.     result = -(strtoul(p, endPtr, base));
  117.     } else {
  118.     if (*p == '+') {
  119.         p += 1;
  120.     }
  121.     result = strtoul(p, endPtr, base);
  122.     }
  123.     if ((result == 0) && (endPtr != 0) && (*endPtr == p)) {
  124.     *endPtr = string;
  125.     }
  126.     return result;
  127. }
  128. @
  129.  
  130.  
  131. 1.3
  132. log
  133. @Lint.
  134. @
  135. text
  136. @d17 2
  137. a18 2
  138. static char rcsid[] = "$Header: strtol.c,v 1.2 88/06/17 18:00:08 ouster Exp $ SPRITE (Berkeley)";
  139. #endif not lint
  140. @
  141.  
  142.  
  143. 1.2
  144. log
  145. @Don't know.
  146. @
  147. text
  148. @d17 1
  149. a17 1
  150. static char rcsid[] = "$Header: strtol.c,v 1.1 88/04/28 17:20:29 ouster Exp $ SPRITE (Berkeley)";
  151. d20 1
  152. @
  153.  
  154.  
  155. 1.1
  156. log
  157. @Initial revision
  158. @
  159. text
  160. @d17 1
  161. a17 1
  162. static char rcsid[] = "$Header: proto.c,v 1.2 88/03/11 08:39:08 ouster Exp $ SPRITE (Berkeley)";
  163. a21 24
  164. #ifndef TRUE
  165. #define TRUE 1
  166. #define FALSE 0
  167. #endif
  168. #ifndef NULL
  169. #define NULL 0
  170. #endif
  171.  
  172. /*
  173.  * The table below is used to convert from ASCII digits to a
  174.  * numerical equivalent.  It maps from '0' through 'z' to integers
  175.  * (100 for non-digit characters).
  176.  */
  177.  
  178. static char cvtIn[] = {
  179.     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,        /* '0' - '9' */
  180.     100, 100, 100, 100, 100, 100, 100,        /* punctuation */
  181.     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,    /* 'A' - 'Z' */
  182.     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  183.     30, 31, 32, 33, 34, 35,
  184.     100, 100, 100, 100, 100, 100,        /* punctuation */
  185.     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,    /* 'a' - 'z' */
  186.     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  187.     30, 31, 32, 33, 34, 35};
  188. d60 1
  189. a60 4
  190.     register int result = 0;
  191.     register unsigned digit;
  192.     int sign;
  193.     int anyDigits = FALSE;
  194. a75 1
  195.     sign = TRUE;
  196. d77 1
  197. a78 1
  198.     sign = FALSE;
  199. d82 1
  200. d84 2
  201. a85 101
  202.  
  203.     /*
  204.      * If no base was provided, pick one from the leading characters
  205.      * of the string.
  206.      */
  207.     
  208.     if (base == 0)
  209.     {
  210.     if (*p == '0') {
  211.         p += 1;
  212.         if (*p == 'x') {
  213.         p += 1;
  214.         base = 16;
  215.         } else {
  216.  
  217.         /*
  218.          * Must set anyDigits here, otherwise "0" produces a
  219.          * "no digits" error.
  220.          */
  221.  
  222.         anyDigits = TRUE;
  223.         base = 8;
  224.         }
  225.     }
  226.     else base = 10;
  227.     } else if (base == 16) {
  228.  
  229.     /*
  230.      * Skip a leading "0x" from hex numbers.
  231.      */
  232.  
  233.     if ((p[0] == '0') && (p[1] == 'x')) {
  234.         p += 2;
  235.     }
  236.     }
  237.  
  238.     /*
  239.      * Sorry this code is so messy, but speed seems important.  Do
  240.      * different things for base 8, 10, 16, and other.
  241.      */
  242.  
  243.     if (base == 8) {
  244.     for ( ; ; p += 1) {
  245.         digit = *p - '0';
  246.         if (digit > 7) {
  247.         break;
  248.         }
  249.         result = (result << 3) + digit;
  250.         anyDigits = TRUE;
  251.     }
  252.     } else if (base == 10) {
  253.     for ( ; ; p += 1) {
  254.         digit = *p - '0';
  255.         if (digit > 9) {
  256.         break;
  257.         }
  258.         result = (10*result) + digit;
  259.         anyDigits = TRUE;
  260.     }
  261.     } else if (base == 16) {
  262.     for ( ; ; p += 1) {
  263.         digit = *p - '0';
  264.         if (digit > ('z' - '0')) {
  265.         break;
  266.         }
  267.         digit = cvtIn[digit];
  268.         if (digit > 15) {
  269.         break;
  270.         }
  271.         result = (result << 4) + digit;
  272.         anyDigits = TRUE;
  273.     }
  274.     } else {
  275.     for ( ; ; p += 1) {
  276.         digit = *p - '0';
  277.         if (digit > ('z' - '0')) {
  278.         break;
  279.         }
  280.         digit = cvtIn[digit];
  281.         if (digit >= base) {
  282.         break;
  283.         }
  284.         result = result*base + digit;
  285.         anyDigits = TRUE;
  286.     }
  287.     }
  288.  
  289.     /*
  290.      * See if there were any digits at all.
  291.      */
  292.  
  293.     if (!anyDigits) {
  294.     p = string;
  295.     }
  296.  
  297.     if (endPtr != NULL) {
  298.     *endPtr = p;
  299.     }
  300.  
  301.     if (sign) {
  302.     return -result;
  303. @
  304.